<template>
    <div class="hr-list">
        <ol class="hr-list__tabs">
            <li
                :class="['hr-list__tabs__item', { 'is-selected': isPublicRoomView }]"
                @click="setRoomView(true)">
                公区
            </li>
            <li
                :class="['hr-list__tabs__item', 'is-right', { 'is-selected': !isPublicRoomView }]"
                @click="setRoomView(false)">
                房间
            </li>
        </ol>
        <div class="hr-list__wrap">
            <div v-if="publicRoom" v-show="isPublicRoomView">
                <!-- 分散式 -->
                <template v-if="isDecentralizedHome">
                    <div class="margin-bottom-20">
                        <Checkbox v-model="searchModel.publicIsNormal" @on-change="handlePublicDeviceFilter(true)">设备正常</Checkbox>
                        <Checkbox v-model="searchModel.publicIsError" @on-change="handlePublicDeviceFilter(false)">设备异常</Checkbox>
                        <i-button type="primary" size="small" @click="openRoom(publicRoom)">管理</i-button>
                        <template v-if="isFullRenting">
                            <span class="margin-left-10" v-if="publicRoom && publicRoom.leases.length">租客: {{publicRoom.cTenantInfo}}</span>
                            <i-button v-else type="primary" size="small" @click="checkInVisible = true">租客入住</i-button>
                        </template>
                    </div>
                    <device-list
                        narrow
                        :room="decentralizedPublicRoom"
                        :home-id="home.id">
                    </device-list>
                </template>
                <!-- 集中式公区 -->
                <template v-if="isCentralizedHome">
                    <div class="margin-bottom-20">
                        <i-button type="primary" size="small" @click="openRoom(publicRoom)">管理</i-button>
                    </div>
                    <PublicRoomCard
                        style="width:460px"
                        v-if="isCentralizedHome"
                        :room="publicRoom"
                        :home-id="home.id"
                    />
                </template>
            </div>
            <div class="hr-list__rooms" v-if="isDecentralizedHome" v-show="!isPublicRoomView">
                <!-- 分散式 -->
                <div
                    class="hr-list__rooms__item"
                    v-for="room in rooms"
                    :key="room.id">
                    <room-card :room="room" :home="home"></room-card>
                </div>
            </div>
            <!-- 集中式 -->
            <div v-if="!isDecentralizedHome" v-show="!isPublicRoomView">
                <Row type="flex" align="middle" :gutter="20" class="margin-bottom-20">
                    <i-col class="flex flex-align-center" :span="6" v-if="hasMultipleBuilding">
                        <span style="width:40px">楼栋</span>
                        <Select v-model="currentBuilding" style="flex:1" @on-change="handleBuildingChange">
                            <Option
                                v-for="building in buildings"
                                :key="building.id"
                                :value="building.id">
                                {{building.room_name}}
                            </Option>
                        </Select>
                    </i-col>
                    <i-col :span="6">
                        <i-input
                            icon="ios-search-strong"
                            placeholder="关键字：房间名"
                            @on-enter="handleRoomSearch"
                            @on-click="handleRoomSearch"
                            v-model.trim="searchModel.roomName">
                        </i-input>
                    </i-col>
                    <i-col :span="6">
                        <Checkbox v-model="searchModel.isEmpty" @on-change="handleSelectEmpty">空置房间</Checkbox>
                        <Checkbox v-model="searchModel.isRented" @on-change="handleSelectRented">已出租</Checkbox>
                        <Checkbox v-model="searchModel.isError">设备异常</Checkbox>
                    </i-col>
                </Row>

                <div class="focus-room">
                    <Spin v-if="loading" fix></Spin>
                    <ol class="focus-room__floors">
                        <li class="focus-room__floors__title">楼层</li>
                        <li
                            :class="{
                                'focus-room__floors__item': true,
                                'is-active': floor === currentFloor
                            }"
                            @click="handleChangeFloor(floor)"
                            v-for="(floor, index) in floors"
                            :key="index">
                            {{floor}}
                        </li>
                    </ol>
                    <div class="focus-room__list">
                        <div class="hr-list__rooms">
                            <div
                                class="hr-list__rooms__item"
                                v-for="room in seletedRooms"
                                :key="room.id">
                                <room-card
                                    :room="room"
                                    :home="home">
                                </room-card>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <CheckIn
            v-if="isFullRenting && checkInVisible"
            :home="home"
            :room="publicRoom"
            @cancelCheckIn="checkInVisible = false"
            @checkInSuccess="handleRefreshRoom(publicRoom.id)"
        />
    </div>
</template>

<script>
    /**
     * 房源详情 - 房间列表
     */
    import cloneDeep from 'lodash/cloneDeep'
// import debounce from 'lodash/debounce';
import bus from '@/libs/event-bus'
import { fetchRoomFromHomeId, fetchRoom } from './util'
import deviceList from './device-list'
import roomCard from './room-card'
import PublicRoomCard from './public-room-card'
import CheckIn from '../../renter/renterCheckIn'

export default {
      name: 'home-detail-room-list',
      props: {
        home: Object
      },
      components: {
        CheckIn,
        roomCard,
        deviceList,
        PublicRoomCard
      },
      data () {
        return {
          /** 展示公区 */
          isPublicRoomView: true,
          publicRoom: null,
          rooms: [],
          /** 集中式或独栋式房源楼层 */
          floors: [],
          currentFloor: '',
          currentBuilding: '',
          buildings: [],
          cacheBuildings: null,
          searchModel: {
            roomName: '',
            isEmpty: false,
            isRented: false,
            isError: false,
            publicIsNormal: false,
            publicIsError: false
          },
          checkInVisible: false,
          timer: null,
          sizes: 100,
          hasMultipleBuilding: null
        }
      },
      computed: {
        isFullRenting () {
          return this.home && this.home.lease_type === 2
        },
        decentralizedPublicRoom () {
          if (!this.publicRoom) return null
          if (!this.isDecentralizedHome) return null
          const { devices: originalDevices, ...rest } = this.publicRoom
          let devices
          if (this.searchModel.publicIsNormal) {
            devices = originalDevices.filter(device => !device.cTooltipContent)
          } else if (this.searchModel.publicIsError) {
            devices = originalDevices.filter(device => !!device.cTooltipContent)
          } else {
            devices = originalDevices
          }
          return { devices, ...rest }
        },
        isDecentralizedHome () { return this.home && this.home.home_type === 1 },
        isCentralizedHome () { return this.home && this.home.home_type === 2 },
        /**
             * 集中式房间列表数组, 避免大量渲染导致卡顿
             * 当房间数量小于100时候直接返回,
             * 否则每次返回n*100个数据, 直到比length总数大
             */
        seletedRooms () {
          if (this.isDecentralizedHome) return []
          if (Array.isArray(this.rooms)) return []
          if (Object.keys(this.rooms).length === 0) return []
          if (this.currentFloor === '') return []
          const { isEmpty, isRented, isError } = this.searchModel
          const result = this.rooms[this.currentFloor].filter(room => {
            let result = true
            if (isEmpty) result = (!room.leases || room.leases.length === 0) && result
            if (isRented) result = (room.leases && room.leases.length > 0) && result
            if (isError) result = (room.devices && room.devices.some(device => !!device.cTooltipContent)) && result
            return result
          })
          const length = result.length
          if (length < 100) return result
          if (this.sizes < length) {
            this.timer = setTimeout(() => {
              this.sizes = this.sizes + 100
            }, 500)
          }
          return result.slice(0, this.sizes)
        }
      },
      created () {
        this.initRooms()
        bus.$on('refresh-room' + this.home.id, this.handleRefreshRoom)
      },
      methods: {
        handleRoomSearch () {
          const { cacheBuildings, buildings } = this
          if (!cacheBuildings || !buildings.length) return
          const { roomName } = this.searchModel
          if (!roomName) {
            this.buildings = cloneDeep(cacheBuildings)
            this.setDefaultView(this.buildings)
          } else {
            const newBuildings = []
            cacheBuildings.forEach(building => {
                        const { floors, rooms, ...buildingInfo } = building; // eslint-disable-line
              const newFloors = []
              const newRooms = {}
              Object.keys(rooms).forEach(floor => {
                if (!rooms[floor] || !rooms[floor].length) return
                const matchRooms = rooms[floor].filter(room => room.room_name.includes(roomName))
                if (matchRooms.length) {
                  newFloors.push(floor)
                  newRooms[floor] = matchRooms
                }
              })
              if (newFloors.length) newBuildings.push({ ...buildingInfo, floors: newFloors, rooms: newRooms })
            })
            if (!newBuildings.length) {
              this.$Message.info('没有匹配的房间')
            } else {
              this.buildings = newBuildings
              this.setDefaultView(newBuildings)
            }
          }
        },
        // handleSearch: debounce(function () {
        //     this.initRooms();
        // }, 200),
        handlePublicDeviceFilter (type) {
          if (type) {
            this.searchModel.publicIsError = false
          } else {
            this.searchModel.publicIsNormal = false
          }
        },
        handleSelectEmpty (val) {
          if (this.searchModel.isRented) this.searchModel.isRented = false
        },
        handleSelectRented () {
          if (this.searchModel.isEmpty) this.searchModel.isEmpty = false
        },
        handleBuildingChange (id) {
          const newBuilding = this.buildings.find(b => b.id === id)
          this.setBuildingRoom(newBuilding.floors, newBuilding.rooms)
        },
        setRoomView (type) {
          this.isPublicRoomView = type
        },
        openRoom (room) {
          bus.$emit('open-room' + this.home.id, room)
        },
        getQuery () {
          const query = { with_device: 1, with_tenant: 1, keyword: this.searchModel.roomName || null }
          return query
        },
        async initRooms () {
          try {
            this.loading = true
            const { id, home_type } = this.home
            const query = this.getQuery()
            const rooms = await fetchRoomFromHomeId(id, query)

            if (rooms) {
              if (home_type === 1) {
                this.renderDecentralizedRooms(rooms)
              } else if (home_type === 2) {
                this.renderCentralizedRooms(rooms)
              }
            }
          } catch (err) {
            console.log(err)
          } finally {
            this.loading = false
          }
        },
        /**
             * 渲染集中式房源,
             * 显示逻辑: 多栋则显示楼栋选项, 只有一栋或是旧集中式, 不显示楼栋信息
             */
        renderCentralizedRooms (rooms) {
          const isBuildingRoom = rooms.some(room => room.room_type === 3)
          /** 独栋式为集中式房源, room_type为3的房间即楼栋列表, 普通房间的building_id即父级楼栋 */
          /** 找出楼栋和普通房间 */
          this.publicRoom = rooms.find(room => room.room_type === 2)
          if (!this.publicRoom) this.publicRoom = { devices: [], cRoomName: '公区', cTenantInfo: '' }
          const [ buildings, plainRooms ] = rooms.reduce(([ buildings, plainRooms ], room) => {
            if (room.room_type === 3) {
              /** 将楼栋初始化, 楼栋下的设备在公区展示 */
              const { devices } = room
              devices.forEach(d => { d.isBuildingDevice = true })
              if (devices && devices.length) this.publicRoom.devices.push(...devices)
              buildings.push({ ...room, rooms: {}, floors: [] })
            } else if (room.room_type === 1) {
              plainRooms.push(room)
            }
            return [ buildings, plainRooms ]
          }, [ [], [] ])
          /** 如果是旧集中式, 默认楼栋 */
          if (!isBuildingRoom) buildings[0] = { id: 'oldVersionFocus', rooms: {}, floors: [] }
          /** 防止搜索房间名导致结构变化 */
          if (!this.hasMultipleBuilding && this.hasMultipleBuilding === null) {
            this.hasMultipleBuilding = buildings.length > 1
          }

          // 将房间置入楼栋中
          plainRooms.forEach(room => {
            const { floor } = room
            let building = buildings.find(b => b.id === room.building_id)
            if (!isBuildingRoom) building = buildings[0]
            if (!building) return
            if (!building.rooms[floor]) building.rooms[floor] = []
            building.rooms[floor].push(room)
            const hasThisFloor = building.floors.some(floorData => floorData === floor)
            if (!hasThisFloor) building.floors.push(floor)
          })

          this.buildings = buildings
          this.cacheBuildings = cloneDeep(buildings)
          this.setDefaultView(buildings)
        },
        setDefaultView (buildings) {
          this.currentBuilding = buildings[0].id
          this.setBuildingRoom(buildings[0].floors, buildings[0].rooms)
        },
        setBuildingRoom (floors, rooms) {
          this.currentFloor = floors[0]
          this.floors = floors
          this.rooms = rooms
        },
        /** 渲染分散式房源 */
        renderDecentralizedRooms (rooms) {
          this.publicRoom = rooms.find(room => room.room_type === 2)
          this.rooms = rooms.filter(room => room.room_type === 1)
        },
        generateFloors (rooms) {
          return rooms.reduce((result, room) => {
            const { room_type, floor } = room
            if (room_type === 2) return result
            if (result.some(addedRoom => addedRoom.floor === floor)) return result
            return result.concat([{ label: floor, floor }])
          }, [])
        },
        handleChangeFloor (floor) {
          if (this.timer) clearTimeout(this.timer)
          this.sizes = 100
          this.currentFloor = floor
        },
        renderRooms (rooms) {
          let publicRoom
          const result = {}
          rooms.forEach(room => {
            if (room.room_type === 2) {
              publicRoom = room
            } else {
              if (!result[room.floor]) result[room.floor] = []
              result[room.floor].push(room)
            }
          })
          return [ publicRoom, result ]
        },
        /**
             * 只更新单个房间信息
             */
        async handleRefreshRoom (roomId) {
          try {
            const room = await fetchRoom(roomId)
            if (!room) return
            if (this.publicRoom.id === roomId) {
              this.publicRoom = room
            } else {
              this.isDecentralizedHome
                ? this.updateDecentralizedRoom(roomId, room)
                : this.updateFocusRoomInfo(roomId, room)
            }
          } catch (err) {
            console.log(err)
          }
        },
        updateDecentralizedRoom (roomId, room) {
          const roomIndex = this.rooms.findIndex(r => r.id === roomId)
          if (roomIndex > -1) this.rooms.splice(roomIndex, 1, room)
        },
        updateFocusRoomInfo (roomId, room) {
          this.buildings.some((building, buildingIndex) => {
            let floor
            let roomIndex
            Object.keys(building.rooms).some(f => {
              const ri = building.rooms[f].findIndex(r => r.id === roomId)
              if (ri > -1) {
                floor = f
                roomIndex = ri
                return true
              }
              return false
            })
            if (roomIndex !== undefined) {
              this.rooms[floor].splice(roomIndex, 1, room)
              this.buildings[buildingIndex].rooms[floor].splice(roomIndex, 1, room)
              return true
            }
            return false
          })
        }
      },
      beforeDestroy () {
        bus.$off('refresh-room' + this.home.id, this.handleRefreshRoom)
      }
    }
</script>

<style lang="less">
    @import url('./room-list.less');
</style>